#pragma once
#include <pthread.h>
#include <string>
#include <iostream>
#include <cstdio>
#include <functional>

namespace ThreadModule
{
    static int num = 1;

    class Thread
    {
    public:
        // 利用包装器包装用户传入的方法！
        using func_t = std::function<void()>; // 传自定义参数

        Thread(func_t func)
            : _tid(0), _ret(nullptr), _isdetach(false), _isrunning(false), _isjoin(false)
        {
            _name = "thread-" + std::to_string(num++);
            _func = func; // 由用户传递执行方法
        }

        void Start()
        {
            if (_isrunning)
                return;
            int n = pthread_create(&_tid, nullptr, run, this);
            if (n != 0)
            {
                perror("Start fasle!");
            }
            else
            {
                std::cout << "成功创建新线程并启动" << std::endl;
                _isrunning = true;
            }
        }

        void Detach()
        {
            if (!_isrunning)
                return;
            if (_isdetach)
                return;
            pthread_detach(_tid);
            _isdetach = true;
            std::cout << "线程被成功分离！" << std::endl;
        }

        void Join()
        {
            // 等待的前提：运行了且没有分离
            if (_isrunning)
            {
                if (!_isdetach)
                {
                    int n = pthread_join(_tid, &_ret);
                    if (n == 0)
                    {
                        _isjoin = true;
                        std::cout << "成功等待线程：" << std::endl;
                    }
                    else
                    {
                        perror("detach error!");
                    }
                }
                else
                {
                    std::cout << "同一个线程不可重复等待！" << std::endl;
                }
            }
        }

        void Stop()
        {
            // 没运行，不能调用
            if (_isrunning)
                return;

            int n = pthread_cancel(_tid);
            if (n == 0)
            {
                std::cout << "线程已终止！" << std::endl;
            }
            else
            {
                perror("Stop error!");
            }
        }

    private:
        // 成员函数有this指针！用静态函数解决
        // 静态函数没有this指针，只有一个参数！
        // 显示的传入参数：this，通过访问成员变量，调用用户传入的方法
        static void *run(void *agrs)
        {
            Thread *thread = static_cast<Thread *>(agrs);
            // 调用用户传入的方法
            thread->_func();
            return nullptr;
        }

        pthread_t _tid;
        std::string _name;
        void *_ret;
        bool _isdetach;
        bool _isrunning;
        bool _isjoin;
        func_t _func;
    };
}